import { Box2, Vector2 } from "three";

export default class SegmentUtil {

    /**
    * 是否在线段上
    * @param target 目标点
    * @param lineStart 线的起点
    * @param lineEnd 线的终点
    */
    static isOnLine(target: Vector2, lineStart: Vector2, lineEnd: Vector2): boolean {
        let error = 0.01;

        let min = lineStart.clone().min(lineEnd);
        let max = lineStart.clone().max(lineEnd);


        if (target.x < (min.x - error)
            || target.x > (max.x + error) || target.y < (min.y - error) || target.y > (max.y + error)) {
            return false;
        }

        let v1 = lineEnd.clone().sub(lineStart);
        let v2 = target.clone().sub(lineStart);
        let cross = v1.cross(v2);

        let dis = Math.abs(cross / Math.sqrt((v1.x * v1.x) + (v1.y * v1.y)));
        if (dis > error * -1 && dis < error) {
            return true;
        }

        return false;
    }



    /** 
    *  求过一点到线段的垂足
   */
    static getSegmentIntersectPoint(segmentA: Array<Vector2>, p: Vector2): Vector2 {
        let a = segmentA[0];
        let a1 = segmentA[1];

        let n_a = a1.clone().sub(a).normalize();
        let n_b_0 = p.clone().sub(a);
        let n_b = n_b_0.normalize();

        let cos = n_a.dot(n_b);
        let dis = n_b_0.length() * cos;

        let result = a.clone().add(n_a.multiplyScalar(dis));

        return result;
    }



    // /** 
    //  * 线段相交
    //  * */
    // static segmentIntersect(segmentA: Array<Vector2>, segmentB: Array<Vector2>): Vector2 {

    //     let segment_normal_a = segmentA[1].clone().sub(segmentA[0]);
    //     let segment_normal_b = segmentB[1].clone().sub(segmentB[0]);

    //     let dot = segment_normal_a.clone().normalize().dot(segment_normal_b.clone().normalize());
    //     let cross = segment_normal_a.clone().normalize().cross(segment_normal_b.clone().normalize());
    //     //是否平行
    //     if (cross == 0) {
    //         return null;
    //     }
    //     //是否相交

    //     let aBox: Box2 = new Box2(segmentA[0].min(segmentA[1]), segmentA[0].max(segmentA[1]));
    //     let bBox: Box2 = new Box2(segmentB[0].min(segmentB[1]), segmentB[0].max(segmentB[1]));

    //     if (aBox.min.x > bBox.max.x || aBox.min.y > bBox.max.y || aBox.max.x < bBox.min.x || aBox.max.y < bBox.min.y) {
    //         return null;
    //     }

    //     //相交且垂直
    //     let p = this.getSegmentIntersectPoint(segmentA, segmentB[0]);


    //     return p;
    // }


    /**
     * 一般方程式求解线段的交点
     * @param segmentA 
     * @param segmentB 
     * @returns 
     */
    static segmentIntersect(segmentA: Array<Vector2>, segmentB: Array<Vector2>): Vector2 {

        let segment_normal_a = segmentA[1].clone().sub(segmentA[0]);
        let segment_normal_b = segmentB[1].clone().sub(segmentB[0]);

        //平行
        let cross = segment_normal_a.clone().normalize().cross(segment_normal_b.clone().normalize());
        //是否平行
        if (cross == 0) {
            return null;
        }

        //相交
        let aBox: Box2 = new Box2(segmentA[0].clone().min(segmentA[1]), segmentA[0].clone().max(segmentA[1]));
        let bBox: Box2 = new Box2(segmentB[0].clone().min(segmentB[1]), segmentB[0].clone().max(segmentB[1]));

        if (aBox.min.x > bBox.max.x || aBox.min.y > bBox.max.y || aBox.max.x < bBox.min.x || aBox.max.y < bBox.min.y) {
            return null;
        }


        //构建直线的一般式
        let aa = segment_normal_a.y;
        let ab = -segment_normal_a.x;
        let ac = segmentA[0].y * segmentA[1].x - segmentA[1].y * segmentA[0].x;

        let ba = segment_normal_b.y;
        let bb = -segment_normal_b.x;
        let bc = segmentB[0].y * segmentB[1].x - segmentB[1].y * segmentB[0].x;

        //分母
        let denominator = aa * bb - ba * ab;
        let y = (ac*ba - bc *aa) / denominator;
        let x = (bc*ab - ac *bb) / denominator;

        let p = new Vector2(x, y);

        return p;
    }

}